﻿using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

namespace CharacterProgressControl.WinRT
{
    [TemplatePart(Name = "PART_mask", Type = typeof(Rectangle))]
    [TemplatePart(Name = "PART_container", Type = typeof(Grid))]
    [TemplatePart(Name = "PART_percentage_text", Type = typeof(TextBlock))]

    [TemplatePart(Name = "PART_foreground_Man1", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Man1", Type = typeof(Path))]
    [TemplatePart(Name = "PART_foreground_Woman1", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Woman1", Type = typeof(Path))]

    [TemplatePart(Name = "PART_foreground_Man2", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Man2", Type = typeof(Path))]
    [TemplatePart(Name = "PART_foreground_Woman2", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Woman2", Type = typeof(Path))]

    [TemplatePart(Name = "PART_foreground_Man3", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Man3", Type = typeof(Path))]
    [TemplatePart(Name = "PART_foreground_Woman3", Type = typeof(Path))]
    [TemplatePart(Name = "PART_outline_Woman3", Type = typeof(Path))]

    public sealed class CProgressControl : ProgressBar
    {
        Rectangle mask;
        Grid container;
        TextBlock percentageText;

        Path foreground_Man1;
        Path outline_Man1;
        Path foreground_Woman1;
        Path outline_Woman1;

        Path foreground_Man2;
        Path outline_Man2;
        Path foreground_Woman2;
        Path outline_Woman2;

        Path foreground_Man3;
        Path outline_Man3;
        Path foreground_Woman3;
        Path outline_Woman3;

        #region DisplayOption DP
        public DisplayOptions DisplayOption
        {
            get { return (DisplayOptions)GetValue(DisplayOptionProperty); }
            set { SetValue(DisplayOptionProperty, value); }
        }

        public static readonly DependencyProperty DisplayOptionProperty =
            DependencyProperty.Register("DisplayOption", typeof(DisplayOptions),
                                                         typeof(CProgressControl),
                                                         new PropertyMetadata(DisplayOptions.ManType1));
        #endregion

        #region TextForeground DP
        public SolidColorBrush TextForeground
        {
            get { return (SolidColorBrush)GetValue(TextForegroundProperty); }
            set { SetValue(TextForegroundProperty, value); }
        }

        public static readonly DependencyProperty TextForegroundProperty =
            DependencyProperty.Register("TextForeground", typeof(SolidColorBrush),
                                                          typeof(CProgressControl),
                                                          new PropertyMetadata(new SolidColorBrush(Colors.DarkGray)));
        #endregion

        public CProgressControl()
        {
            this.DefaultStyleKey = typeof(CProgressControl);
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            foreground_Man1 = GetTemplateChild("PART_foreground_Man1") as Path;
            outline_Man1 = GetTemplateChild("PART_outline_Man1") as Path;
            foreground_Woman1 = GetTemplateChild("PART_foreground_Woman1") as Path;
            outline_Woman1 = GetTemplateChild("PART_outline_Woman1") as Path;

            foreground_Man2 = GetTemplateChild("PART_foreground_Man2") as Path;
            outline_Man2 = GetTemplateChild("PART_outline_Man2") as Path;
            foreground_Woman2 = GetTemplateChild("PART_foreground_Woman2") as Path;
            outline_Woman2 = GetTemplateChild("PART_outline_Woman2") as Path;

            foreground_Man3 = GetTemplateChild("PART_foreground_Man3") as Path;
            outline_Man3 = GetTemplateChild("PART_outline_Man3") as Path;
            foreground_Woman3 = GetTemplateChild("PART_foreground_Woman3") as Path;
            outline_Woman3 = GetTemplateChild("PART_outline_Woman3") as Path;

            switch (DisplayOption)
            {
                case DisplayOptions.ManType1:
                    foreground_Man1.Visibility = Visibility.Visible;
                    outline_Man1.Visibility = Visibility.Visible;
                    break;
                case DisplayOptions.WomanType1:
                    foreground_Woman1.Visibility = Visibility.Visible;
                    outline_Woman1.Visibility = Visibility.Visible;
                    break;
                case DisplayOptions.ManType2:
                    foreground_Man2.Visibility = Visibility.Visible;
                    outline_Man2.Visibility = Visibility.Visible;
                    break;
                case DisplayOptions.WomanType2:
                    foreground_Woman2.Visibility = Visibility.Visible;
                    outline_Woman2.Visibility = Visibility.Visible;
                    break;
                case DisplayOptions.ManType3:
                    foreground_Man3.Visibility = Visibility.Visible;
                    outline_Man3.Visibility = Visibility.Visible;
                    break;
                case DisplayOptions.WomanType3:
                    foreground_Woman3.Visibility = Visibility.Visible;
                    outline_Woman3.Visibility = Visibility.Visible;
                    break;
                default:
                    break;
            }

            mask = GetTemplateChild("PART_mask") as Rectangle;
            container = GetTemplateChild("PART_container") as Grid;
            percentageText = GetTemplateChild("PART_percentage_text") as TextBlock;

            Width = double.IsNaN(Width) ? 50 : Width;
            Height = double.IsNaN(Height) ? 135 : Height;

            Minimum = double.IsNaN(Minimum) ? 0 : Minimum;
            Maximum = double.IsNaN(Maximum) ? 100 : Maximum;

            if (mask != null)
            {
                var percentageValue = Value / Maximum;
                var awayMargin = percentageValue * Height;
                var percentageString = string.Empty;

                if (percentageValue > 0)
                    percentageString = (percentageValue * 100).ToString("##");
                else if (percentageValue == 0)
                    percentageString = "0";

                percentageText.Text = string.Format("{0}%", string.IsNullOrEmpty(percentageString) ? "0" : percentageString);

                mask.Margin = new Thickness(0, 0, 0, awayMargin);
            }

            container.Clip = new RectangleGeometry
            {
                Rect = new Rect(0, 0, Width, Height)
            };

            mask.Width = Width;
            mask.Height = Height;
        }

        protected override void OnValueChanged(double oldValue, double newValue)
        {
            base.OnValueChanged(oldValue, newValue);

            if (Value < Minimum)
            {
                Value = Minimum;
            }

            if (Value > Maximum)
            {
                Value = Maximum;
            }

            if (mask != null)
            {
                var percentageValue = Value / Maximum;
                var awayMargin = percentageValue * Height;
                var percentageString = string.Empty;

                if (percentageValue > 0)
                    percentageString = (percentageValue * 100).ToString("##");
                else if (percentageValue == 0)
                    percentageString = "0";

                percentageText.Text = string.Format("{0}%", string.IsNullOrEmpty(percentageString) ? "0" : percentageString);

                mask.Margin = new Thickness(0, 0, 0, awayMargin);
            }
        }
    }
}
